/**
 * @func 第二版记忆函数 {自定义方式存储key}
 * @param {function} func 
 * @param {function} hasher 
 * @returns {function}
 */
var memorize = function(func, hasher) {
    var memoize = function(key) {
        var cache = memoize.cache;
        var address = '' + (hasher ? hasher.apply(this, arguments) : key);
        if (cache[address]==null) {
            cache[address] = func.apply(this, arguments);
        }
        return cache[address];
    };
    // 闭包空间
    // 属性永生
    memoize.cache = {};
    return memoize;
};

// var add = function(a, b, c) {
//     return a + b + c
//   }
  
//   var memoizedAdd = memorize(add)
  
//   memoizedAdd(1, 2, 3) // 6
//   memoizedAdd(1, 2, 4) // 6

// 改进
// var memoizedAdd = memorize(add, function(){
//     var args = Array.prototype.slice.call(arguments)
//     return JSON.stringify(args)
// })

// console.log(memoizedAdd(1, 2, 3)) // 6
// console.log(memoizedAdd(1, 2, 4)) // 7

// 用记忆函数计算斐波那契数列
var count = 0;
var fibonacci = function(n) {
    count++;
    return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};

fibonacci = memorize(fibonacci)

for (var i = 0; i <= 10; i++) {
    fibonacci(i)
}

console.log(count) // 12
